package cn.incoder.moyun.config.tenant;

import cn.incoder.moyun.api.tenant.TenantApi;
import cn.incoder.moyun.common.enums.WebFilterOrderEnum;
import cn.incoder.moyun.core.db.TenantDatabaseInterceptor;
import cn.incoder.moyun.core.web.TenantContextWebFilter;
import cn.incoder.moyun.service.tenant.TenantFrameworkService;
import cn.incoder.moyun.service.tenant.TenantFrameworkServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;

@AutoConfiguration
@ConditionalOnProperty(prefix = "moyun.tenant", value = "enable", matchIfMissing = true) // 允许使用 moyun.tenant.enable=false 禁用多租户
@EnableConfigurationProperties(TenantProperties.class)
public class YudaoTenantAutoConfiguration {

    @Bean
    @Lazy
    public TenantFrameworkService tenantFrameworkService(TenantApi tenantApi) {
        return new TenantFrameworkServiceImpl(tenantApi);
    }

    // ========== AOP ==========
    // 提供@TenantIgnore注解支持，用于忽略特定方法的多租户逻辑

//    @Bean
//    public TenantIgnoreAspect tenantIgnoreAspect() {
//        return new TenantIgnoreAspect();
//    }

    // ========== DB ==========
    //租户拦截器，MyBatis Plus的租户拦截器自动在SQL中添加租户条件

    @Bean
    public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties properties) {
        return new TenantLineInnerInterceptor(new TenantDatabaseInterceptor(properties));
    }

    // ========== WEB ==========

    @Bean
    public FilterRegistrationBean<TenantContextWebFilter> tenantContextWebFilter() {
        FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new TenantContextWebFilter());
        registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER);
        return registrationBean;
    }

    // ========== Security ==========

//    @Bean
//    public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter(TenantProperties tenantProperties,
//                                                                                   WebProperties webProperties,
//                                                                                   GlobalExceptionHandler globalExceptionHandler,
//                                                                                   TenantFrameworkService tenantFrameworkService) {
//        FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>();
//        registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties,
//                globalExceptionHandler, tenantFrameworkService));
//        registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER);
//        return registrationBean;
//    }

    // ========== MQ ==========

//    @Bean
//    public TenantRedisMessageInterceptor tenantRedisMessageInterceptor() {
//        return new TenantRedisMessageInterceptor();
//    }
//
//    @Bean
//    @ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate")
//    public TenantRabbitMQInitializer tenantRabbitMQInitializer() {
//        return new TenantRabbitMQInitializer();
//    }
//
//    @Bean
//    @ConditionalOnClass(name = "org.apache.rocketmq.spring.core.RocketMQTemplate")
//    public TenantRocketMQInitializer tenantRocketMQInitializer() {
//        return new TenantRocketMQInitializer();
//    }
//
//    // ========== Job ==========
//
//    @Bean
//    public TenantJobAspect tenantJobAspect(TenantFrameworkService tenantFrameworkService) {
//        return new TenantJobAspect(tenantFrameworkService);
//    }

    // ========== Redis ==========

//    @Bean
//    @Primary // 引入租户时，tenantRedisCacheManager 为主 Bean
//    public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
//                                                     RedisCacheConfiguration redisCacheConfiguration,
//                                                     YudaoCacheProperties yudaoCacheProperties,
//                                                     TenantProperties tenantProperties) {
//        // 创建 RedisCacheWriter 对象
//        RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
//        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
//                BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
//        // 创建 TenantRedisCacheManager 对象
//        return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration, tenantProperties.getIgnoreCaches());
//    }

}
